package com.sqlsession.mysql;

import com.sqlsession.DataBase;
import com.sqlsession.database.BaseDateSource;
import com.sqlsession.database.CColumn;
import com.sqlsession.database.CTable;

import java.sql.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class MySqlDateSource extends BaseDateSource {
    private static final String URL = "jdbc:mysql://%s:%s/%s?useSSL=false";

    public MySqlDateSource(DataBase dataBase) {
        super(dataBase);
    }

    @Override
    public String getUrl() {
        DataBase dataBase = getDataBase();
        return String.format(URL, dataBase.getHost(), dataBase.getPort(), dataBase.getName());
    }

    @Override
    public List<CTable> getSelectTablesSql(ResultSet resultSet) throws SQLException {
        List<CTable> cTables = new LinkedList<>();
        if (resultSet == null) {
            Connection connection = getConnection();
            StringBuilder builder = new StringBuilder();
            builder.append("Select table_name as TABLE_NAME,TABLE_COMMENT as REMARKS, TABLE_TYPE as TABLE_TYPE from INFORMATION_SCHEMA.TABLES where table_schema = ");
            builder.append("'");
            builder.append(getDataBase().getName());
            builder.append("'");
            String sql = builder.toString();
            PreparedStatement stmt = connection.prepareStatement(sql);
            resultSet = stmt.executeQuery(sql);
        }
        while (resultSet.next()) {
            String remarks = resultSet.getString("REMARKS");
            String table_name = resultSet.getString("TABLE_NAME");
            String tableType = resultSet.getString("TABLE_TYPE");  //表类型
            if (!getFilter().filterTable(table_name)) {
                continue;
            }
            CTable cTable = new CTable(getDataBase());
            cTable.setName(table_name);
            cTable.setCommon(remarks);
            cTables.add(cTable);

        }
        return cTables;
    }

    private void test(ResultSetMetaData data) {
        try {
            int columnCount = data.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = data.getColumnName(i);// 获得指定列的列名
                int columnType = data.getColumnType(i);// 获得指定列的列值
                String columnTypeName = data.getColumnTypeName(i);// 获得指定列的数据类型名
                String catalogName = data.getCatalogName(i);// 所在的Catalog名字
                String columnClassName = data.getColumnClassName(i);// 对应数据类型的类
                int columnDisplaySize = data.getColumnDisplaySize(i);// 在数据库中类型的最大字符个数
                String columnLabel = data.getColumnLabel(i);// 默认的列的标题
                String schemaName = data.getSchemaName(i);// 获得列的模式
                int precision = data.getPrecision(i);// 某列类型的精确度(类型的长度)
                int scale = data.getScale(i);// 小数点后的位数
                String tableName = data.getTableName(i);// 获取某列对应的表名
                boolean isAutoInctement = data.isAutoIncrement(i);// 是否自动递增
                boolean isCurrency = data.isCurrency(i);// 在数据库中是否为货币型
                int isNullable = data.isNullable(i);// 是否为空
                boolean isReadOnly = data.isReadOnly(i);// 是否为只读
                boolean isSearchable = data.isSearchable(i);// 能否出现在where中

                System.out.println("获得列" + i + "的字段名称:" + columnName);

//                System.out.println("获得列" + i + "的类型,返回SqlType中的编号:"+ columnType);
//
//                System.out.println("获得列" + i + "的数据类型名:" + columnTypeName);
//
//                System.out.println("获得列" + i + "所在的Catalog名字:"+ catalogName);
//
                System.out.println("获得列" + i + "对应数据类型的类:" + columnClassName);
//
                System.out.println("获得列" + i + "在数据库中类型的最大字符个数:" + columnDisplaySize);
//
//                System.out.println("获得列" + i + "的默认的列的标题:" + columnLabel);
//
//                System.out.println("获得列" + i + "的模式:" + schemaName);
//
//                System.out.println("获得列" + i + "类型的精确度(类型的长度):" + precision);
//
//                System.out.println("获得列" + i + "小数点后的位数:" + scale);
//
//                System.out.println("获得列" + i + "对应的表名:" + tableName);
//
//                System.out.println("获得列" + i + "是否自动递增:" + isAutoInctement);
//
//                System.out.println("获得列" + i + "在数据库中是否为货币型:" + isCurrency);
//
//                System.out.println("获得列" + i + "是否为空:" + isNullable);
//
//                System.out.println("获得列" + i + "是否为只读:" + isReadOnly);
//
//                System.out.println("获得列" + i + "能否出现在where中:"+ isSearchable);
                System.out.println("------------------------------------");

            }
        } catch (Exception e) {

        }
    }

    @Override
    public List<CColumn> getColumns(CTable cTable) throws SQLException {
        List<CColumn> cColumns = new LinkedList<>();
        String name = cTable.getName();
        Connection connection = getConnection();
        //String sql = "Select COLUMN_NAME COLUMN_NAME, DATA_TYPE TYPE_NAME, COLUMN_COMMENT REMARKS from INFORMATION_SCHEMA.COLUMNS Where table_name = "+cTable.getName() + " AND table_schema =  "+cTable.getDataBase().getName();
        StringBuilder builder = new StringBuilder();
        builder.append("select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ");
        builder.append("\"");
        builder.append(cTable.getName());
        builder.append("\"");
        builder.append(" and ");
        builder.append(" TABLE_SCHEMA = ");
        builder.append("\"");
        builder.append(cTable.getDataBase().getName());
        builder.append("\"");
        String sql = builder.toString();

        PreparedStatement stmt = connection.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery(sql);
        ResultSetMetaData data = rs.getMetaData();
        //test(data);
        //Map<String, Boolean> primaryKeys = new HashMap<>();
        while (rs.next()) {

            String columnName = rs.getString("COLUMN_NAME");
            if (!getFilter().filterColumn(cTable.getName(), columnName)) {
                continue;
            }
            String REMARKS = rs.getString("COLUMN_COMMENT");
            String IS_NULLABLE = rs.getString("IS_NULLABLE");  //是否允许为null
            String DATA_TYPE = rs.getString("DATA_TYPE"); //对应的java.sql.Types的SQL类型(列类型ID)
            String TYPE_NAME = rs.getString("COLUMN_TYPE"); //java.sql.Types类型名称(列类型名称)
            int CHAR_OCTET_LENGTH = rs.getInt("CHARACTER_OCTET_LENGTH");// 对于 char 类型，该长度是列中的最大字节数
            String columnKey = rs.getString("COLUMN_KEY");//
            //int DECIMAL_DIGITS = rs.getInt("DECIMAL_DIGITS"); //小数位数
//            String columnDef = rs.getString("COLUMN_DEF");  //默认值


//            int COLUMN_SIZE = rs.getInt("COLUMN_SIZE"); //列大小
//
//            String SQL_DATA_TYPE = rs.getString("SQL_DATA_TYPE");
//            String SQL_DATETIME_SUB = rs.getString("SQL_DATETIME_SUB");
//
//            String ORDINAL_POSITION = rs.getString("ORDINAL_POSITION");
//

            boolean isNUllAble = IS_NULLABLE.toUpperCase().equals("yes".toUpperCase());//IS_NULLABLE.equals("YES");
            CColumn cColumn = new CColumn(cTable);
            cColumn.setCommon(REMARKS);
            cColumn.setName(columnName);
            cColumn.primaryKey(columnKey.toUpperCase().equals("pri".toUpperCase()));
            cColumn.setType(DATA_TYPE);
            cColumn.setLength(CHAR_OCTET_LENGTH);
            cColumn.setAllowBlank(isNUllAble);
            cColumns.add(cColumn);
        }
        rs.close();
        return cColumns;
    }
}
